#include "udisk.h"
#include "udiskmanager.h"
#include <QStringList>
#include <QObject>
#include <QMap>

enum UDiskError {
    NoError,
    MountSuccess = NoError,
    UnDetected,
    MultipleUsb,
    MountFail,
    ReadOnly,
};

Udisk::Udisk(const QString &mountDir) : m_mountDir(mountDir), m_errorCode(NoError)
{
}

Udisk::~Udisk()
{
    umount();
}

static UDiskError mount(const QString &mountDir, QString &mountDevice)
{
    QStringList devices = UdiskManager::enumDevices();
    if (devices.count() <= 0)
    {// 未检测到u盘
        return UnDetected;
    }

    foreach (const QString &device, devices)
    {// 挂载u盘
        if (UdiskManager::isMount(device))
        {// 已挂载，先卸载
            UdiskManager::umount(device);
        }

        if (UdiskManager::mount(device, mountDir))
        {// 挂载成功
            mountDevice = device;            
            return UdiskManager::isMountDirWritable(device, mountDir) ? MountSuccess : ReadOnly;
        }
    }

    return MountFail;
}

bool Udisk::mount(bool allowMountedReadonly)
{
    UDiskError errorCode = ::mount(m_mountDir, m_device);
    bool ret = (errorCode == NoError);
    if (!ret && allowMountedReadonly)
    {
        ret = (errorCode == ReadOnly);
    }

    m_errorCode = ret ? MountSuccess : errorCode;
    return ret;
}

void Udisk::umount()
{
    if (UdiskManager::isMount(m_device, m_mountDir))
    {
        UdiskManager::umount(m_device);
        UdiskManager::deleteEmptyDirectory(m_mountDir);
    }
}

static QString error(UDiskError code)
{
    static const QMap<UDiskError, QString> mapper = {
        { UnDetected, QObject::tr("U disk not detected.") },
        { MultipleUsb, QObject::tr("There are multiple USB drives")},
        { MountFail, QObject::tr("U disk not recognized.") },
        { ReadOnly, QObject::tr("Read-only U disk, cannot write") },
    };

    return mapper.contains(code) ? mapper[code] : "";
}

QString Udisk::error() const
{
    return ::error((UDiskError)m_errorCode);
}

QString Udisk::mountDir() const
{
    return UdiskManager::toNormalizedPath(m_mountDir);
}

QString Udisk::mountDevice() const
{
    return m_device;
}



